{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2285300b-3bc1-4004-9d55-90114ce84df6",
   "metadata": {},
   "source": [
    "# Persistent configuration"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0a0ae95-a85e-4231-ad3d-34714ec5395f",
   "metadata": {},
   "source": [
    "Both static and interactive plots produced through DataMapPlots can be customized through many settings.\n",
    "When such customizations become more numerous and pervasive through one's usage,\n",
    "copy-pasting the settings in every invocation of `create_plot` and friends can become cumbersome.\n",
    "The solution to this problem is to write these common custom settings up in the **DataMapPlot configuration file**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2162b13-1f78-4cca-9b6e-f986530fdebe",
   "metadata": {},
   "source": [
    "When DataMapPlot is first imported in any Python code, it creates this configuration file in the \"most appropriate place\" given one's computing platform."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "8ca503e7-709a-4cea-af8e-f60dcf0e6cd6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import datamapplot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "405e05c0-6c42-43ef-8a48-c079880e2fb2",
   "metadata": {},
   "outputs": [],
   "source": [
    "from datamapplot.config import ConfigManager\n",
    "cfg = ConfigManager()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8f64cb6e-c086-4a5b-8590-ff7569cf4e23",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".config/datamapplot/config.json\n"
     ]
    }
   ],
   "source": [
    "from pathlib import Path\n",
    "print(ConfigManager()._config_file.relative_to(Path.home()))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdeb7e18-ed88-4877-9ee3-d84859b52bf6",
   "metadata": {},
   "source": [
    "The default configurationm file includes minimal settings that echo our users' typical purposes for bending away from the default parameter values of the main DataMapPlot routines."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e78744cd-a6e9-4e5f-872e-05b05ec262b2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"dpi\": 100,\n",
      "  \"figsize\": [\n",
      "    10,\n",
      "    10\n",
      "  ],\n",
      "  \"cdn_url\": \"unpkg.com\",\n",
      "  \"font_family\": \"Roboto\"\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "print(cfg._config_file.read_text())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e9b2f3a-68f5-49cd-ab51-668509eef624",
   "metadata": {},
   "source": [
    "Most parameters that carry a default value for `create_plot`, `create_interactive_plot` and other interface routines can be set by editing this JSON file.\n",
    "Yet, some of the most basic plot ingredients cannot be set through this file.\n",
    "An attempt to do so will raise a `ConfigError` exception when creating a plot."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec9dcbce-94c5-4494-8e71-f2bf1f42c1a4",
   "metadata": {},
   "source": [
    "## Setting persistent configuration through Python code"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7294dcd3-e43d-4eca-92fa-00c2ddcfc5b1",
   "metadata": {},
   "source": [
    "`ConfigManager` is a [singleton class](https://www.patterns.dev/vanilla/singleton-pattern/) whose indexing getting and setting work just like a dictionary.\n",
    "Thus, custom settings can be set through Python code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "7a9d45f9-2e10-4186-be87-51dffd1bf795",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n"
     ]
    }
   ],
   "source": [
    "print(cfg[\"dpi\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "0deeb77d-0b16-4742-a718-abf653e59cb4",
   "metadata": {},
   "outputs": [],
   "source": [
    "cfg[\"font_family\"] = \"Roboto\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82bc72f0-1f91-4b7f-a649-7b7ab6c62b9a",
   "metadata": {},
   "source": [
    "These configuration settings can be made to persist between sessions by saving to the configuration file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "86c2c736-699e-4fd4-bb53-241ddc9c3e62",
   "metadata": {},
   "outputs": [],
   "source": [
    "cfg.save()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
